package com.enation.app.javashop.core.trade.cart.service.impl;

import com.enation.app.javashop.core.base.CachePrefix;
import com.enation.app.javashop.core.base.message.GoodsCartCountMsg;
import com.enation.app.javashop.core.base.rabbitmq.AmqpExchange;
import com.enation.app.javashop.core.goods.model.vo.GoodsSkuVO;
import com.enation.app.javashop.core.promotion.newcomer.model.dos.NewcomerDO;
import com.enation.app.javashop.core.promotion.shetuan.model.dos.ShetuanGoodsDO;
import com.enation.app.javashop.core.promotion.shetuan.service.ShetuanGoodsManager;
import com.enation.app.javashop.core.promotion.tool.model.dos.PromotionGoodsDO;
import com.enation.app.javashop.core.promotion.tool.model.enums.PromotionTypeEnum;
import com.enation.app.javashop.core.promotion.tool.model.vo.PromotionVO;
import com.enation.app.javashop.core.promotion.tool.service.PromotionGoodsManager;
import com.enation.app.javashop.core.trade.TradeErrorCode;
import com.enation.app.javashop.core.trade.cart.model.enums.CartSourceType;
import com.enation.app.javashop.core.trade.cart.model.enums.CheckedWay;
import com.enation.app.javashop.core.trade.cart.model.vo.CartPromotionVo;
import com.enation.app.javashop.core.trade.cart.model.vo.CartSkuOriginVo;
import com.enation.app.javashop.core.trade.cart.model.vo.CartSkuVO;
import com.enation.app.javashop.core.trade.cart.service.CartPromotionManager;
import com.enation.app.javashop.core.trade.converter.TradePromotionConverter;
import com.enation.app.javashop.core.trade.order.model.dos.OrderItemsDO;
import com.enation.app.javashop.core.trade.order.model.dto.OrderQueryParam;
import com.enation.app.javashop.core.trade.order.model.enums.OrderStatusEnum;
import com.enation.app.javashop.core.trade.order.model.enums.ServiceStatusEnum;
import com.enation.app.javashop.core.trade.order.service.OrderQueryManager;
import com.enation.app.javashop.framework.cache.Cache;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.security.model.Buyer;
import com.enation.app.javashop.framework.util.DateUtil;
import com.enation.app.javashop.framework.util.DictUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author JFeng
 * @date 2020/12/11 18:14
 */

public abstract class AbstractCartDataManagerImpl {

    @Autowired
    private OrderQueryManager orderQueryManager;

    @Autowired
    private PromotionGoodsManager promotionGoodsManager;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    @Qualifier("tradeDaoSupport")
    private DaoSupport daoSupport;

    @Autowired
    private CartPromotionManager cartPromotionManager;

    @Autowired
    private ShetuanGoodsManager shetuanGoodsManager;

    @Autowired
    private Cache cache;



    public Integer checkEnableQuantity(int num, GoodsSkuVO sku) {
        if (sku == null) {
            throw new ServiceException(TradeErrorCode.E451.code(), "商品已失效，请刷新购物车");
        }

        //读取sku的可用库存
        Integer enableQuantity = sku.getEnableQuantity();

        //如果sku的可用库存小于等于0或者小于用户购买的数量，则不允许购买
        if (enableQuantity.intValue() <= 0 || enableQuantity.intValue() < num) {
            throw new ServiceException(TradeErrorCode.E451.code(), "商品库存已不足，不能购买。");
        }
        return enableQuantity;
    }


    public CartSkuOriginVo updateSkuVo(int skuId, int num, String cartSourceType, GoodsSkuVO sku, Integer enableQuantity, List<CartSkuOriginVo> originList) {
        CartSkuOriginVo skuVo = findSku(skuId, originList);

        //购物车中已经存在，试着更新数量
        if (skuVo != null && sku.getLastModify().equals(skuVo.getLastModify())) {

            //判断是商品否被修改
            int oldNum = skuVo.getNum();
            int newNum = oldNum + num;

            //检查购物车优惠活动有效期,如有过期活动则删除过期活动,并重置数量
            if (cartPromotionManager.checkPromotionInvalid(skuId)) {
                newNum = num;
            }
            //增加数量的话库存已经不足，则最多为可用库存
            if (newNum > enableQuantity) {
                newNum = enableQuantity;
            }
            skuVo.setNum(newNum);

        } else {
            //先清理一下 如果商品无效的话
            originList.remove(skuVo);
            //购物车中不存在此商品，则新建立一个
            skuVo = new CartSkuOriginVo();
            //将相同的属性copy
            BeanUtils.copyProperties(sku, skuVo);
            //再设置加入购物车的数量
            skuVo.setNum(num);
            // CST
            skuVo.setCartSourceType(cartSourceType);

            originList.add(skuVo);
        }
        return skuVo;
    }

    public void cartCount(int num, int memberId, GoodsSkuVO sku) {
        //购物车商品加购统计消息
        GoodsCartCountMsg goodsCartCountMsg = new GoodsCartCountMsg();
        goodsCartCountMsg.setMemberId(memberId);
        goodsCartCountMsg.setSkuVO(sku);
        goodsCartCountMsg.setNum(num);
        amqpTemplate.convertAndSend(AmqpExchange.GOODS_CART_COUNT,
                AmqpExchange.GOODS_CART_COUNT + "_ROUTING", goodsCartCountMsg);
    }


    public void checkLimit(int skuId, Integer activityId) {
        // 查询sku对应的所有单品优惠
        List<PromotionGoodsDO> promotionGoodsList=promotionGoodsManager.getPromotionBySkuId(skuId);

        for (PromotionGoodsDO promotionGoodsDO : promotionGoodsList) {
            // 购物车类型
            if(promotionGoodsDO.getPromotionType().equals(PromotionTypeEnum.SHETUAN.name())){
            }
            // 限购计算（社团团购 限时秒杀限购）
            if (activityId.equals(promotionGoodsDO.getActivityId())) {
                //skuVo.setLimitNum(promotionGoodsDO.getLimitNum());
                //checkLimitNum(promotionGoodsDO.getLimitNum(), skuVo.getNum(), skuVo.getSkuId());
            }
        }
    }

    /**
     * 商品限购 一天一次下单
     */
    public void checkLimitNum(Integer limitNum ,Integer skuNum ,Integer skuId) {
        if (limitNum != null && limitNum > 0 ) {
            if(limitNum < skuNum){
                throw new ServiceException(TradeErrorCode.E451.code(), "商品限购:" + limitNum);
            }
            LocalDateTime startTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);

            OrderQueryParam orderQueryParam = new OrderQueryParam();
            orderQueryParam.setMemberId(UserContext.getBuyer().getUid());
            orderQueryParam.setSkuId(skuId);
            orderQueryParam.setStartTime(startTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()/1000);
            orderQueryParam.setEndTime(DateUtil.getDateline());
            // 售后订单和取消订单不在限购订单指标行列
            orderQueryParam.setAntiOrderStatus(OrderStatusEnum.CANCELLED.value());
            orderQueryParam.setServiceStatus(ServiceStatusEnum.NOT_APPLY.value());

            List<OrderItemsDO> orderItems = orderQueryManager.listOrderSku(orderQueryParam);
            Integer totalNum=skuNum;
            if(orderItems.size()>0){
                for (OrderItemsDO orderItemsDO : orderItems) {
                    totalNum += orderItemsDO.getNum();
                }
                if(totalNum>limitNum){
                    throw new ServiceException(TradeErrorCode.E451.code(), "超过当日商品限购数:" + limitNum);
                }
            }
        }
    }

    /**
     * 新人购限制选择商品总数
     * @param activityId
     * @param originList
     */
    public void checkNewcomerLimitChoice(Integer activityId,List<CartSkuOriginVo> originList ) {
        long currentTime = DateUtil.getDateline();
        NewcomerDO newcomerDO = daoSupport.queryForObject("SELECT * FROM es_newcomer WHERE newcomer_id=? and start_time<=? and end_time>=?",
                NewcomerDO.class, activityId,currentTime,currentTime);
        if (newcomerDO == null) {
            return;
        }
        Integer limitChoice = newcomerDO.getLimitNum();
        int currentSkuCount = 0;
        if (limitChoice != null && limitChoice > 0) {
            for (CartSkuOriginVo cartSkuOriginVo : originList) {
                List<CartPromotionVo> promotionVos = cartSkuOriginVo.getSingleList().stream()
                        .filter(cartPromotionVo -> cartPromotionVo.getPromotionType().equals(PromotionTypeEnum.NEWCOMER.name())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(promotionVos)) {
                    currentSkuCount++;
                }
            }
        }
        if (currentSkuCount > limitChoice) {
            throw new ServiceException("1000", "新人购限制选择商品数量：" + limitChoice);
        }
    }

    /**
     * 读取当前会员购物原始数据key
     *
     * @param checkedWay 获取方式
     * @return
     */
    public String getOriginKey(CheckedWay checkedWay) {

        String cacheKey = "";
        //如果会员登录了，则要以会员id为key
        Buyer buyer = UserContext.getBuyer();
        if (buyer != null) {
            if (checkedWay.equals(CheckedWay.CART)) {
                cacheKey = CachePrefix.CART_ORIGIN_DATA_PREFIX.getPrefix() + buyer.getUid();
            } else if (checkedWay.equals(CheckedWay.BUY_NOW)) {
                cacheKey = CachePrefix.BUY_NOW_ORIGIN_DATA_PREFIX.getPrefix() + buyer.getUid();
            }

        }
        return cacheKey;
    }

    /**
     * 读取当前会员购物原始数据key
     *
     * @param checkedWay 获取方式
     * @return
     */
    public String getShetuanKey(CheckedWay checkedWay) {

        String cacheKey = "";
        //如果会员登录了，则要以会员id为key
        Buyer buyer = UserContext.getBuyer();
        if (buyer != null) {
            if (checkedWay.equals(CheckedWay.CART)) {
                cacheKey = CachePrefix.CART_SHETUAN_DATA_PREFIX.getPrefix() + buyer.getUid();
            } else if (checkedWay.equals(CheckedWay.BUY_NOW)) {
                cacheKey = CachePrefix.BUY_NOW_SHETUAN_DATA_PREFIX.getPrefix() + buyer.getUid();
            }

        }

        return cacheKey;
    }

    /**
     * 根据skuid 查找某个sku
     *
     * @param skuId      要查找的skuid
     * @param originList sku list
     * @return 找到返回sku，找不到返回Null
     */
    public CartSkuOriginVo findSku(int skuId, List<CartSkuOriginVo> originList) {
        for (CartSkuOriginVo cartSkuOriginVo : originList) {
            if (cartSkuOriginVo.getSkuId().equals(skuId)) {
                return cartSkuOriginVo;
            }
        }
        return null;

    }


    /**
     * 为某个cart sku 填充促销信息
     *
     * @param cartSkuVo
     */
    public void fillPromotion(CartSkuOriginVo cartSkuVo, Integer activityId) {

        //找到当前要使用活动的类型
        PromotionTypeEnum usedType = null;

        //单品活动集合^
        List<CartPromotionVo> singleList = new ArrayList<>();

        //组合活动集合
        List<CartPromotionVo> groupList = new ArrayList<>();

        // 商品有效的促销活动
        List<PromotionGoodsDO> doList = this.getGoodsEnablePromotion(cartSkuVo.getSkuId(), cartSkuVo.getSellerId());

        for (PromotionGoodsDO promotionGoodsDO : doList) {
            // 促销商品判别sku_id
            if(promotionGoodsDO.getProductId()!=null && !promotionGoodsDO.getProductId().equals(cartSkuVo.getSkuId())){
                continue;
            }

            CartPromotionVo promotionGoodsVO = TradePromotionConverter.promotionGoodsDOConverter(promotionGoodsDO);

            //目前只有满减是组合活动
            if (PromotionTypeEnum.FULL_DISCOUNT.name().equals(promotionGoodsDO.getPromotionType())) {
                groupList.add(promotionGoodsVO);
            } else {
                //找到要参加的活动
                if (promotionGoodsDO.getActivityId().equals(activityId)) {
                    usedType = PromotionTypeEnum.myValueOf(promotionGoodsDO.getPromotionType());
                }
                singleList.add(promotionGoodsVO);
            }
        }

        cartSkuVo.setGroupList(groupList);
        cartSkuVo.setSingleList(singleList);

        //如果没有指定使用的活动，试着使用第一个
        if (activityId == null && doList.size() > 0) {
            PromotionGoodsDO promotionGoodsDO = doList.get(0);
            activityId = promotionGoodsDO.getActivityId();
            usedType = PromotionTypeEnum.myValueOf(promotionGoodsDO.getPromotionType());
        }

        if (usedType != null && activityId != null) {
            //使用要使用的活动
            PromotionVO promotionVO = cartPromotionManager.usePromotion(cartSkuVo.getSellerId(), cartSkuVo.getSkuId(), activityId, usedType);
            // 第一次添加时校验库存
            cartSkuVo.setLimitNum(promotionVO.getLimitNum());
            checkLimitNum(promotionVO.getLimitNum(),cartSkuVo.getNum(),cartSkuVo.getSkuId());
            if(promotionVO.getPromotionType().equals(PromotionTypeEnum.SHETUAN.name())){
                cartSkuVo.setPickTime(promotionVO.getShetuanGoodsVO().getPickTime());
            }
        }


    }


    /**
     * 读取某个商品参与的所有活动
     *
     * @param skuId
     * @param sellerId
     * @return
     */
    public List<PromotionGoodsDO> getGoodsEnablePromotion(Integer skuId, Integer sellerId) {

        long currTime = DateUtil.getDateline();

        //读取此商品参加的活动
        String sql = "select   goods_id, product_id, start_time, end_time, activity_id, promotion_type,title,num,price " +
                "from es_promotion_goods where ( product_id=? or goods_id=-1)  and start_time<=? and end_time>=? and seller_id = ? ORDER BY promotion_type DESC";
        List<PromotionGoodsDO> resultList = this.daoSupport.queryForList(sql, PromotionGoodsDO.class, skuId, currTime, currTime, sellerId);

        return resultList;
    }


    public ShetuanGoodsDO checkIsShetuan(Integer skuId, Integer activityId) {
        return shetuanGoodsManager.checkIsShetuan(skuId, activityId);
    }


    public CartSkuOriginVo getCartSkuOriginVo( GoodsSkuVO sku, int checked,List<CartSkuOriginVo> originList,CartSourceType cartSourceTypeEnum ) {
        int skuId = sku.getSkuId();
        //这是本次要返回的sku
        AtomicReference<CartSkuOriginVo> skuOriginVo = new AtomicReference<>();
        originList.forEach(cartSku -> {
            if (cartSku.getSkuId() == skuId) {
                cartSku.setChecked(checked);
                skuOriginVo.set(cartSku);
                return;
            }
        });

        CartSkuOriginVo cartSkuOriginVo = skuOriginVo.get();
        if (cartSkuOriginVo != null) {
            String originKey = cartSourceTypeEnum == CartSourceType.SHETUAN_CART ? this.getShetuanKey(CheckedWay.CART) : this.getOriginKey(CheckedWay.CART);
            cache.put(originKey, originList);
        }
        return cartSkuOriginVo;
    }


    public List<CartSkuOriginVo> deleteCartSkus(Integer[] skuIds, List<CartSkuOriginVo> originList) {
        List<CartSkuOriginVo> newList = new ArrayList<>();
        originList.forEach(cartSku -> {

            //查找是否要删除
            //如果不删除压入到新的list中
            if (!ArrayUtils.contains(skuIds, cartSku.getSkuId())) {
                newList.add(cartSku);
            }

        });
        return newList;
    }



    public CartSourceType getCartSourceTypeBySeller(Integer sellerId) {
        String dictValue = DictUtils.getDictValue("", "SHETUAN_SELLER", "SHETUAN_SELLER");
        return StringUtils.isNotEmpty(dictValue) && dictValue.contains(","+sellerId+",")?CartSourceType.SHETUAN_CART:CartSourceType.COMMON_CART;
    }


    public void operatePromotion(Integer activityId, CartSkuOriginVo skuVo) {
        //填充可用的促销数据
        this.fillPromotion(skuVo, activityId);

        // 限购数量
        cartPromotionManager.checkLimitNum(skuVo.getLimitNum(), skuVo.getNum(), skuVo.getSkuId());
    }

}
